package com.legal.service.speech_recognition.Impl;

import com.huawei.sis.bean.response.AsrCustomShortResponse;
import com.huawei.sis.exception.SisException;
import com.legal.domain.result.Result;
import com.legal.service.speech_recognition.VoiceRecognition;
import com.legal.utils.HuaweiSisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author xiaopeng
 * @version 1.0
 */
@Service
@Slf4j
public class VoiceRecognitionImpl implements VoiceRecognition {

    @Value("${huawei.sis.ak}")
    private String ak;

    @Value("${huawei.sis.sk}")
    private String sk;

    @Value("${huawei.sis.region}")
    private String region;

    @Value("${huawei.sis.project-id}")
    private String projectId;

    @Value("${audio.temp.dir:/tmp/audio}")
    private String tempAudioDir;

    @Override
    public Result<String> voiceRecognize(MultipartFile audioFile, String language) {
        // 1. 验证文件
        if (audioFile.isEmpty()) {
            return Result.error("请上传音频文件");
        }

        // 2. 验证文件格式
        String originalFilename = audioFile.getOriginalFilename();
        if (!originalFilename.toLowerCase().endsWith(".wav")) {
            return Result.error("仅支持WAV格式音频");
        }

        // 3. 保存临时文件
        String tempFilePath = saveTempFile(audioFile);
        if (tempFilePath == null) {
            return Result.error("文件保存失败");
        }

        try {
            // 4. 初始化语音识别工具
            HuaweiSisUtil sisUtil = HuaweiSisUtil.getInstance(ak, sk, region, projectId);

            // 5. 设置识别参数
            Map<String, String> options = new HashMap<>();
            options.put("audioFormat", "wav"); // 文件格式，如wav等
            options.put("property", getPropertyString(language)); // 属性字符串，language_sampleRate_domain, 如chinese_8k_common
            options.put("addPunc", "yes"); // 设置是否添加标点

            // 6. 调用识别
            AsrCustomShortResponse result = sisUtil.recognizeShortAudio(tempFilePath, options);

            // 7. 删除临时文件
            boolean deleted = deleteTempFile(tempFilePath);
            if (!deleted) {
                log.warn("未能删除临时音频文件: {}", tempFilePath);
            }

            return Result.ok(result.getResult().getText());
        } catch (SisException e) {
            deleteTempFile(tempFilePath); // 异常时也尝试删除
            return Result.ok("语音识别失败: " + e.getErrorMsg());
        } finally {
            // 确保临时文件被删除
            boolean deleted = deleteTempFile(tempFilePath);
            if (!deleted) {
                log.warn("未能删除临时音频文件: {}", tempFilePath);
            }
        }

    }

    // 替换原来的删除代码
    private boolean deleteTempFile(String filePath) {
        try {
            Path path = Path.of(filePath);
            if (Files.exists(path)) {
                boolean deleted = Files.deleteIfExists(path);
                if (!deleted) {
                    log.warn("文件删除失败: {}", filePath);
                    return false;
                }
                log.debug("临时文件已删除: {}", filePath);
                return true;
            }
            return true; // 文件不存在视为删除成功
        } catch (IOException e) {
            log.error("删除临时文件时出错: {}", filePath, e);
            return false;
        }
    }


    /**
     * 根据语言选择属性字符串
     */
    private String getPropertyString(String language) {
        return switch (language.toLowerCase()) {
            case "english" -> "english_8k_common";
            case "cantonese" -> "chinese_8k_cantonese";
            default -> // 默认中文普通话
                    "chinese_8k_common";
        };
    }

    /**
     * 保存临时文件
     *
     * @param file 上传的文件
     * @return 保存后的文件路径，如果失败返回null
     */
    private String saveTempFile(MultipartFile file) {
        // 生成唯一文件名
        String filename = UUID.randomUUID().toString() + ".wav";
        String filePath = tempAudioDir + File.separator + filename;

        try {
            // 使用NIO的Files.createDirectories替代File.mkdirs()
            Path directory = Path.of(tempAudioDir);
            if (!Files.exists(directory)) {
                try {
                    Files.createDirectories(directory);
                    log.debug("创建目录成功: {}", tempAudioDir);
                } catch (IOException e) {
                    log.error("创建目录失败: {}", tempAudioDir, e);
                    return null;
                }
            }

            // 使用NIO的Files.copy替代transferTo
            Path targetPath = Path.of(filePath);
            try (InputStream inputStream = file.getInputStream()) {
                Files.copy(inputStream, targetPath, StandardCopyOption.REPLACE_EXISTING);
                log.debug("文件保存成功: {}", filePath);
                return filePath;
            }
        } catch (IOException e) {
            log.error("保存文件失败: {}", filePath, e);
            return null;
        }
    }

    /**
     * 解析识别结果
     */
    private String parseResult(String jsonResult) {
        // 这里简单返回原始JSON，实际可根据需要解析
        return jsonResult;
    }
}
